from service import Service
from model.project import ProjectDao
from model.sprint import SprintDao
from model.requirement import RequirementDao

from lib.validator import Validator
from lib.form import Form
from bson.objectid import ObjectId
import time




class ProjectService(Service):
    def __init__(self):
        self.dao = ProjectDao()
    
    def get_project(self, sid):
        """
        Argument:
            sid -- string type
        """
        if sid != '':
            oid = ObjectId(sid)
            project = self.dao.find_one({'_id':oid})
            return self.get_dict(project)
        else:
            return None

        
    def delete_project(self, sid):
        if sid != '':
            oid = ObjectId(sid)
            self.dao.remove({'_id':oid})
        
    def get_projects(self, query={}):
        """ Get the projects for rendering the html
        """
        projects = self.dao.find(query)
        
        if projects is not None:
            _projects = []
            for project in projects:
                _projects.append(self.get_dict(project))
            return _projects
        else:
            return []


    def submit_project(self, _dict, mode):
        """
        Return:
        The '_id' value of to_save or [None] if manipulate is False and to_save has no _id field.
        """
        _input = self.get_dao_input(_dict, mode)
        
        # following are hidden fields
        if mode == 'edit':
            _input['created'] = _dict['created']
        else:
            _input['created'] = time.time()
        return self.dao.save(_input)


    def get_project_tree(self):
        _projects = self.dao.find()
        sprint_dao = SprintDao()
        projects = [] 
        for project in _projects:
            project_id = str(project['_id'])
            project_name = '<a href="/project_view"><span class="glyphicon glyphicon-folder-open"></span> ' + project['name'] + '</a>'
            
            backlog = {'id':'p-'+project_id, 'type':'b', 'label': '<a href="/backlog"><span class="glyphicon glyphicon-folder-open"></span> Backlog</a>'}
            
            sprints = []
            _sprints = sprint_dao.find({'project_id':str(project['_id'])})
            for sprint in _sprints:
                sprint_id = str(sprint['_id'])
                sprint_name = '<a href="/sprint_view"><span class="glyphicon glyphicon-folder-open"></span> ' + sprint['name'] + '</a>'
                sprints.append({'id':'s-'+sprint_id, 'type':'s','label':sprint_name})
            
            projects.append({'id':project_id, 'type':'p', 'label':project_name, 'children': [backlog] + sprints})
            
        return [{'id':'0', 'type':'h','label':'<a href="/home"><span class="glyphicon glyphicon-home"></span> Home</a>', 'children':projects}]
    
    def get_tree_datas(self):
        projects = self.dao.all()
        sprint_dao = SprintDao()
        requirement_dao = RequirementDao()
        _projects = []
        for project in projects:
            sprints = sprint_dao.find({'project_id':project['_id']})
            _sprints = []
            for sprint in sprints:
                _specs = []
                specs = requirement_dao.find({'sprint_id':sprint['_id']})
                for spec in specs:
                    _specs.append({'id':str(spec['_id']), 'label':spec['name']})
                    
                sid = str(sprint['_id'])
                label = '<a href="/sprint_view/' + sid + '">' + sprint['name'] + '</a>'
                if _specs == []:
                    _sprints.append({'id':sid, 'label':label})
                else:
                    _sprints.append({'id':sid, 'label':label, 'children':_specs})
            if _sprints == []:
                _projects.append({'id':str(project['_id']), 'label':project['name']})
            else:
                _projects.append({'id':str(project['_id']), 'label':project['name'], 'children':_sprints})
        return _projects
                

class ProjectValidator(Validator):
    def __init__(self):
        Validator.__init__(self)
              
        self.rules = {'name': { 
                                'required' : [None, True],
                                'minlength':[None, 1],
                                'maxlength':[None, 256]
                                },
                      'description': { 
                                'maxlength':[None, 256]
                                }
        }

    
class ProjectForm(Form):
    """ Submit user form
    """
    def __init__(self):
        """Only accept POST request
        """
        Form.__init__(self)
        self.validator = ProjectValidator()
        
        if self.is_submitted():
            self.errors = self.validator.validate(self.input)


    def has_error(self):
        return self.errors != []
